/*
 * @Author: zhang zhijiang 2824735304@qq.com
 * @Date: 2024-12-11 16:02:08
 * @LastEditors: zhang zhijiang 2824735304@qq.com
 * @LastEditTime: 2024-12-11 16:02:26
 * @FilePath: /linux/test_12_11/work.c
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define N 5      // 页面数目
#define LENGTH 1000  // 页面访问串的长度
#define P 3      // 每个进程的页框数
#define TOTAL_FRAMES 6  // 全局页框数目

// 生成页面访问串
void generate_page_access_sequence(int sequence[], int length, float p) {
    int current_page = rand() % N;  // 随机选择一个初始页面
    sequence[0] = current_page;
    
    for (int i = 1; i < length; i++) {
        if ((float)rand() / RAND_MAX < p) {
            sequence[i] = current_page;  // 留在当前页面
        } else {
            current_page = rand() % N;  // 随机选择其他页面
            sequence[i] = current_page;
        }
    }
}

// 计算缺页率
float calculate_page_faults(int sequence[], int length, int num_frames) {
    int page_faults = 0;
    int frames[num_frames];
    for (int i = 0; i < num_frames; i++) {
        frames[i] = -1;  // 初始化页框为无效值
    }

    for (int i = 0; i < length; i++) {
        int found = 0;
        for (int j = 0; j < num_frames; j++) {
            if (frames[j] == sequence[i]) {
                found = 1;  // 找到页面，不发生缺页
                break;
            }
        }

        if (!found) {
            page_faults++;
            int replace_index = rand() % num_frames;  // 随机选择一个页框替换
            frames[replace_index] = sequence[i];  // 替换页面
        }
    }

    return (float)page_faults / length;  // 返回缺页率
}

// 模拟局部策略实验
void local_policy_experiment(int sequence[], int length) {
    // 分成两个进程
    int seq_process1[length / 2];
    int seq_process2[length / 2];
    for (int i = 0; i < length / 2; i++) {
        seq_process1[i] = sequence[i];
        seq_process2[i] = sequence[length / 2 + i];
    }

    // 计算两个进程的缺页率
    float page_faults_process1 = calculate_page_faults(seq_process1, length / 2, P);
    float page_faults_process2 = calculate_page_faults(seq_process2, length / 2, P);

    printf("局部策略下：\n");
    printf("进程1的缺页率：%.4f\n", page_faults_process1);
    printf("进程2的缺页率：%.4f\n", page_faults_process2);
}

// 模拟全局策略实验
void global_policy_experiment(int sequence[], int length) {
    float page_faults = calculate_page_faults(sequence, length, TOTAL_FRAMES);

    printf("全局策略下：\n");
    printf("总缺页率：%.4f\n", page_faults);
}

int main() {
    srand(time(0));  // 用当前时间作为随机数种子

    // 模拟页面访问序列
    int sequence[LENGTH];
    float p = 0.8;  // 下一次访问相同页面的概率

    generate_page_access_sequence(sequence, LENGTH, p);

    // 模拟局部策略
    local_policy_experiment(sequence, LENGTH);

    // 模拟全局策略
    global_policy_experiment(sequence, LENGTH);

    return 0;
}
